package com.jetpackframework.retrofit;

import com.jetpackframework.http.HttpUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;

import okhttp3.OkHttpClient;

public class Retrofit {
    private Map<Class,RetrofitInterface> retrofitInterfaceMap;
    private Map<Class,Object> interMap;
    private static Retrofit retrofit;
    private Retrofit(){
        retrofitInterfaceMap = new HashMap<>();
        interMap = new HashMap<>();
        load();
    }
    public static synchronized Retrofit getInstance(){
        if (retrofit == null){
            retrofit = new Retrofit();
        }
        return retrofit;
    }
    public void load(){
        ServiceLoader<RetrofitInterface> load = ServiceLoader.load(RetrofitInterface.class);
        Iterator<RetrofitInterface> iterator = load.iterator();
        while (iterator.hasNext()){
            RetrofitInterface next = iterator.next();
            retrofitInterfaceMap.put(next.getAnnotation(),next);
        }

    }
    public <T> T create(Class<T> clazz){
        Annotation[] annotations = clazz.getAnnotations();
        if (annotations.length != 1){
            throw new IllegalArgumentException("You cannot annotate this class with more than one annotation");
        }
        synchronized (this) {
            Object o = interMap.get(annotations[0].annotationType());
            if (o != null) {
                return (T) o;
            }
            RetrofitInterface retrofitInterface = retrofitInterfaceMap.get(annotations[0].annotationType());
            o = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{clazz}, retrofitInterface);
            interMap.put(annotations[0].annotationType(), o);
            return (T) o;
        } 
    }

    public static class Builder{

        public Builder client(OkHttpClient client) {
            HttpUtil.getInstance().init(client);
            return this;
        }
        public Builder addResponseConverter(ResponseBodyConverter<String,?> converter){
            HttpUtil.getInstance().addResponseConverter(converter);
            return this;
        }
        public Retrofit builder() {
            return new Retrofit();
        }
    }

}
